package com.zhuzi.batch.config;

import com.alibaba.fastjson.JSON;
import com.ibm.mq.jms.MQConnectionFactory;
import com.ibm.mq.spring.boot.MQConfigurationProperties;
import com.ibm.mq.spring.boot.MQConnectionFactoryCustomizer;
import com.ibm.mq.spring.boot.MQConnectionFactoryFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jms.JmsProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsOperations;
import org.springframework.jms.core.JmsTemplate;

import javax.jms.JMSException;
import java.util.List;

/**
 * @author zhuzi
 * 2023/12/27 23:26
 */
@Slf4j
@Configuration
public class CacheConnFactoryConfig {
    @Value("${ibm.mq.ccsid}")
    private Integer ccsid;
    @Value("${ibm.mq.receive-timeout}")
    private Long receiveTimeout;

    @Value("${ibm.mq.concurrency}")
    private String concurrency;

    @Bean
    public CachingConnectionFactory cachingJmsConnectionFactory(MQConfigurationProperties properties,
                                                                ObjectProvider<List<MQConnectionFactoryCustomizer>> factoryCustomizers, JmsProperties jmsProperties) throws JMSException {

        log.info("设置cachingconnection");
        System.out.println(JSON.toJSONString(properties));
        System.out.println(JSON.toJSONString(jmsProperties));
        JmsProperties.Cache cacheProperties = jmsProperties.getCache();
        MQConnectionFactory wrappedConnectionFactory = createConnectionFactory(properties, factoryCustomizers);
        wrappedConnectionFactory.setCCSID(ccsid);
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(wrappedConnectionFactory);
        connectionFactory.setCacheConsumers(cacheProperties.isConsumers());
        connectionFactory.setCacheProducers(cacheProperties.isProducers());
        connectionFactory.setSessionCacheSize(cacheProperties.getSessionCacheSize());
        connectionFactory.setReconnectOnException(true);
        return connectionFactory;
    }

    /**
     * 配置JMS模板:
     * 重要：不设置setReceiveTimeout时，
     * 当队列为空，从队列中取出消息的方法将会一直挂起直到队列内有消息
     *
     * @param cachingConnectionFactory
     * @return
     */
    @Bean("jmsOperations")
    public JmsOperations jmsOperations(CachingConnectionFactory cachingConnectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory(cachingConnectionFactory);
        //jmsTemplate.setReceiveTimeout(2000);
        return jmsTemplate;
    }

    /**
     * 配置DefaultJmsListenerContainerFactory,
     * 用@JmsListener注解来监听队列消息时候，尤其存在多个监听的时候，
     * 通过实例化配置DefaultJmsListenerContainerFactory来控制消息分发
     *
     * @param cachingConnectionFactory
     * @return
     */
    @Bean(name = "jmsListenerContainerFactorys")
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(CachingConnectionFactory cachingConnectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(cachingConnectionFactory);
        //设置连接数，如果对消息消费有顺序要求，这里建议设置为"1-1"
        factory.setConcurrency(concurrency);
        //重连间隔时间
        factory.setRecoveryInterval(receiveTimeout);
        return factory;
    }

    private static MQConnectionFactory createConnectionFactory(MQConfigurationProperties properties,
                                                               ObjectProvider<List<MQConnectionFactoryCustomizer>> factoryCustomizers) {
        return new MQConnectionFactoryFactory(properties, factoryCustomizers.getIfAvailable()).createConnectionFactory(MQConnectionFactory.class);
    }

}
